package dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

// Make a proxy as how methods on Developer calls as per the developer.
public class DeveloperHandling implements InvocationHandler {

	// having Developer as a instance variable
	Developer employee;

	// Constructor of class setting the value of the Developer instance variable
	public DeveloperHandling(Developer employee) {
		this.employee = employee;
	}

	// InvocationHandler interface has a method by name 'invoke' which returns 
	// back an Object. It works on the principle of reflection. 
	// Each time a call is made by Developer on its setter and getter this
	// method will be called first.
	// This method takes in three arguments :
	// 1. Dynamically created proxy object
	// 2. Method and information regarding the method which needs to be called.
	// 3. Plus what arguments called method takes to fulfill the calling process.
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws IllegalAccessException {

		try {
			// Method class has a method by getName() , which returns
			// back the method name which is called by the Developer.
			if (method.getName().startsWith("get")) {
				// Method class has a method by name invoke().
				// This method invokes employee methods and passing
				// the arguments to it, based on the if condition.
				return method.invoke(employee, args);
			}

			// In order to set restriction on developer to not able to change 
			// state of role, salary and rating 
			// if condition on fulfillment throws IllegalAccessException
			// because a developer has no right to set his salary,
			// role and rate himself. It is duty of his manager to
			// which he reports
			else if (method.getName().equals("setRole")) {
				throw new IllegalAccessException();
			} else if (method.getName().equals("setSalary")) {
				throw new IllegalAccessException();
			} else if (method.getName().equals("setRating")) {
				throw new IllegalAccessException();
			}

		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

		return null;
	}

}